﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;

namespace memo
{
    /// <summary>
    /// A témát megvalósító osztály.
    /// </summary>
    [Serializable]
    public class Topic
    {

        #region Class getter and setter.
        /// <summary>
        /// A topic címe. Nem lehet null, vagy üres.
        /// </summary>
        public string Title
        {
            get
            {
                return myTitle;
            }
            set
            {
                if (!string.IsNullOrWhiteSpace(value))
                {
                    myTitle = value;
                }
                else
                {
                    myTitle = "Untitled";
                }
            }
        }

        /// <summary>
        /// A topic leírása, összefoglalása. Lehet null vagy üres.
        /// </summary>
        public string ShortDescription { get; set; }

        /// <summary>
        /// A Topic-hoz tartozó al-topicok listája.
        /// </summary>
        public List<SubTopic> SubTopics { get; set; }

        /// <summary>
        /// Visszaadja/beállítja a Topic ikonját. Nem lehet null.
        /// </summary>
        public string Icon
        {
            get
            {
                return myIcon;
            }
            set
            {
                if (value != null)
                {
                    myIcon = value;
                }
                else
                {
                    myIcon = "DEFAULT.png";
                }
            }
        }

        /// <summary>
        /// Visszaadja, hogy az adott Topicot mennyire tudja a felhasználó.
        /// </summary>
        /// <returns></returns>
        public int GetKnowledgePercent()
        {
            double percent = 0;
            int counter = 0;
            if (SubTopics != default(List<SubTopic>))
            {
                foreach (SubTopic subtopic in SubTopics)
                {
                    if (subtopic != null)
                    {
                        if (subtopic.Contents != default(List<Content>))
                        {
                            foreach (Content content in subtopic.Contents)
                            {
                                if (content != null)
                                {
                                    percent += content.GetKnowledgePercent();
                                }
                            }
                            counter += subtopic.Contents.Count;
                        }
                    }
                }
                percent = percent / counter;
            }
            else
            {
                percent = 100;
            }
            return (int)percent;
        }

        /// <summary>
        /// Nullára állítja a Topic tudásszázalékát.
        /// </summary>
        public void ResetKnowledgePercent()
        {
            if (SubTopics != default(List<SubTopic>))
            {
                foreach (SubTopic subtopic in SubTopics)
                {
                    if (subtopic != null)
                    {
                        if (subtopic.Contents != default(List<Content>))
                        {
                            foreach (Content content in subtopic.Contents)
                            {
                                if (content != null)
                                {
                                    content.ResetKnowledgePercent();
                                }
                            }
                        }
                    }
                }
            }
        }

        /// <summary>
        /// Százra állítja a Topic tudásszázalékát.
        /// </summary>
        public void FullKnowledgePercent()
        {
            if (SubTopics != default(List<SubTopic>))
            {
                foreach (SubTopic subtopic in SubTopics)
                {
                    if (subtopic != null)
                    {
                        if (subtopic.Contents != default(List<Content>))
                        {
                            foreach (Content content in subtopic.Contents)
                            {
                                if (content != null)
                                {
                                    content.FullKnowledgePercent();
                                }
                            }
                        }
                    }
                }
            }
        }
        #endregion

        #region Definition of the class' constructors.
        /// <summary>
        /// Konstruktor az osztály használatához csak a cím megadásával.
        /// </summary>
        /// <param name="title">A topic címe. Nem lehet null!</param>
        public Topic(string title)
            : this(title, null, null, null)
        { }

        /// <summary>
        /// Konstruktor az osztály használatához, altémák megadása nélkül.
        /// </summary>
        /// <param name="title">A téma címe. Nem lehet null!</param>
        /// <param name="shortDescription">Rövid leírás a téma tartalmáról.</param>
        public Topic(string title, string shortDescription)
            : this(title, shortDescription, null, null)
        { }

        /// <summary>
        /// Konstruktor az osztály használatához, altémák megadása nélkül.
        /// </summary>
        /// <param name="title">A téma címe. Nem lehet null!</param>
        /// <param name="shortDescription"></param>
        /// <param name="subTopic"></param>
        public Topic(string title, string shortDescription, List<SubTopic> subTopic)
            : this(title, shortDescription, subTopic, null)
        { }

        /// <summary>
        /// Konstruktor az osztály használatához, inicializálás egyszerre több altémával.
        /// </summary>
        /// <param name="title">A téma címe. Nem lehet null!</param>
        /// <param name="shortDescription">Rövid leírás a téma tartalmáról.</param>
        /// <param name="subTopic">Az altémák.</param>
        /// <param name="icon">A Topic ikonja.</param>
        public Topic(string title, string shortDescription, List<SubTopic> subTopic, string icon)
        {
            if (!string.IsNullOrWhiteSpace(title))
            {
                myTitle = title;
            }
            else
            {
                myTitle = "Untitled";
            }
            ShortDescription = shortDescription;
            if (icon != null)
            {
                Icon = icon;
            }
            else
            {
                Icon = "DEFAULT.png";
            }
            SubTopics = subTopic;
        }
        #endregion

        #region Add one item List type fields.
        /// <summary>
        /// Egy SubTopic hozzáadása.
        /// </summary>
        /// <param name="subTopic">Hozzáadni kívánt SubTopic.</param>
        /// <returns>Igazat ad vissza ha a művelet sikeres volt.</returns>
        public bool AddSubTopic(SubTopic subTopic)
        {
            if (SubTopics != null)
            {
                SubTopics.Add(subTopic);
                return true;
            }
            return false;
        }
        #endregion

        #region Remove one item List type fields.
        /// <summary>
        /// Törli a megadott indexű SubTopicot.
        /// </summary>
        /// <param name="index">A törlendő SubTopic indexe.</param>
        /// <returns>Igazat ad vissza ha a művelet sikeres volt.</returns>
        public bool RemoveSubTopic(int index)
        {
            if (SubTopics != null)
            {
                if (SubTopics.Count > index && index >= 0)
                {
                SubTopics.RemoveAt(index);
                return true;
                }
            }
            return false;
        }
        #endregion

        #region Clear List type filelds.
        /// <summary>
        /// Törli az összes SubTpoicot.
        /// </summary>
        /// <returns>Igazat ad vissza ha a művelet sikeres volt.</returns>
        public bool ClearSubTopics()
        {
            if (SubTopics != null)
            {
                SubTopics.Clear();
                return true;
            }
            return false;
        }
        #endregion

        #region Swap List type elements.
        /// <summary>
        /// Felcserél két SubTpoicot.
        /// </summary>
        /// <param name="from">Az egyik felcserélendő elem ahonna áthelyezzük.</param>
        /// <param name="to">A másik felcserélendő elem ahová az előzőt tesszük.</param>
        /// <returns>Igazat ad vissza ha a művelet sikeres volt.</returns>
        public bool SwapSubTopics(int from, int to)
        {
            if (SubTopics != null)
            {
                if (SubTopics.Count > from && from >= 0 && SubTopics.Count > to && to >= 0)
                {
                SubTopic Swap = SubTopics[from];
                SubTopics[from] = SubTopics[to];
                SubTopics[to] = Swap;
                return true;
                }
            }
            return false;
        }
        #endregion

        #region Object class overwritten methods.
        /// <summary>
        /// Checks if the topics have the exact same title, short description, and the same subtopics.
        /// </summary>
        /// <param name="obj">The compared Topic</param>
        /// <returns>bool</returns>
        public override bool Equals(object obj)
        {
            bool equals = false;
            Topic topic = obj as Topic;

            if ((topic != null) && (this.GetType() == topic.GetType()))
            {
                if (this.GetHashCode() == topic.GetHashCode())
                {
                    if (this.myTitle == topic.myTitle && this.ShortDescription == topic.ShortDescription)
                    {
                        // kommentelj
                        if (this.SubTopics == null && topic.SubTopics == null)
                        {
                            equals = true;
                        }
                        else
                        {
                            if (this.SubTopics.Count == topic.SubTopics.Count)
                            {
                                int i;
                                // bool-t hozz létre plusszba külön
                                for (i = 0; i < this.SubTopics.Count; i++)
                                {
                                    if (this.SubTopics[i] == topic.SubTopics[i])
                                    {
                                        continue;
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }
                                if (i == this.SubTopics.Count)
                                {
                                    equals = true;
                                }
                            }
                        }
                    }
                }
            }
            return equals;
        }

        /// <summary>
        /// Generates the hashcode for a Topic.
        /// </summary>
        /// <returns>The hashcode</returns>
        public override int GetHashCode()
        {
            int hash = 0;
            hash = (hash * 7) + myTitle.GetHashCode(); // note: title can't be null, so no checking is needed.
            if (ShortDescription != null)
            {
                hash = (hash * 7) + ShortDescription.GetHashCode();
            }
            if (SubTopics != null)
            {
                foreach (SubTopic subtopic in SubTopics)
                {
                    if (subtopic != null)
                    {
                        hash = (hash * 7) + subtopic.GetHashCode();
                    }
                }
            }

            return hash;
        }
        #endregion

        #region Class private field.
        /// <summary>
        /// A Topic ikonja.
        /// </summary>
        private string myIcon;

        /// <summary>
        /// A Topic címe.
        /// </summary>
        private string myTitle;
        #endregion
    }
}